package org.laobai.permission.service.impl;

import org.laobai.permission.config.UserThreadLocal;
import org.laobai.permission.entity.Menu;
import org.laobai.permission.entity.Role;
import org.laobai.permission.entity.RoleMenu;
import org.laobai.permission.entity.UserRole;
import org.laobai.permission.exception.PermissionException;
import org.laobai.permission.mapper.RoleMapper;
import org.laobai.permission.service.MenuService;
import org.laobai.permission.service.RoleMenuService;
import org.laobai.permission.service.RoleService;
import org.laobai.permission.service.UserRoleService;
import org.laobai.permission.struct.PageResult;
import org.laobai.permission.vo.SearchVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jiusan
 * @since 2021-11-17
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private RoleMenuService roleMenuService;
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private MenuService menuService;
    @Autowired
    private UserThreadLocal userThreadLocal;

    @Override
    public boolean hasRole(String roleNameZh){

        Integer id = userThreadLocal.getUser().getId();
        List<UserRole> list = userRoleService.list(new QueryWrapper<UserRole>().eq("uid", id));
        List<String> roleNames = listByIds(list.stream().map(UserRole::getRid).collect(Collectors.toList()))
                .stream().map(Role::getNameZh).collect(Collectors.toList());
        if(CollectionUtils.isEmpty(roleNames)){
            return false;
        }
        return roleNames.contains(roleNameZh);
    }


    @Override
    public PageResult<Role> page(Integer currPage, Integer pageSize, SearchVO vo) {
        // 分页
        Page<Role> rolePage = new Page<>(currPage, pageSize);

        // 条件查询
        QueryWrapper<Role> wrapper = new QueryWrapper<>();

        if (Objects.nonNull(vo)) {
            String keyWord = vo.getKeyWord();
            if (!StringUtils.isEmpty(keyWord)) {
                wrapper.like("name", keyWord).or().like("nameZh", keyWord);
            }
            String begin = vo.getBegin();
            String end = vo.getEnd();
            if ((!StringUtils.isEmpty(begin)) && (!StringUtils.isEmpty(end))) {
                wrapper.between("created", begin, end);
            }
        }
        rolePage = page(rolePage, wrapper);
        return PageResult.of(rolePage.getRecords(), rolePage.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveRole(Role role) {
        // 设置基础信息
        role.setCreated(new Date());

        // 保存主表
        save(role);
        // 准备中间表数据
        addMiddle(role);
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateRole(Role role) {
        // 先修改主表信息
        updateById(role);
        // 修改中间表
        // 先删
        delByRid(role.getId());
        // 后加
        addMiddle(role);

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean delById(Long id) {
        delByRid(id.intValue());
        return removeById(id);
    }

    @Override
    public boolean delByIds(List<Long> ids) {
        return removeByIds(ids);
    }

    @Override
    public List<Integer> getMidsByRid(Integer rid) {
        List<RoleMenu> list = roleMenuService.list(new QueryWrapper<RoleMenu>().eq("rid", rid));
        //  若集合为空，返回空集合
        if (CollectionUtils.isEmpty(list)) {
            return Collections.EMPTY_LIST;
        }
//        ArrayList<Integer> result = new ArrayList<>();
//        list.forEach(item->{
//            result.add(item.getMid());
//        });
        // 获取子节点数据
        // 所有的菜单ID的集合
        Set<Integer> mids = list.stream().map(RoleMenu::getMid).collect(Collectors.toSet());
        // 查询所有菜单，过滤path为空的菜单
        return menuService.listByIds(mids)
                .stream()
                .filter(item -> {
                    return !StringUtils.isEmpty(item.getPath());
                })
                .map(Menu::getId)
                .collect(Collectors.toList());
    }

    /**
     * 删除中间表数据
     *
     * @param rid
     */
    private void delByRid(Integer rid) {
        QueryWrapper<RoleMenu> wrapper = new QueryWrapper<RoleMenu>().eq("rid", rid);
        roleMenuService.remove(wrapper);
    }


    /**
     * 添加中间表信息
     *
     * @param role
     */
    private void addMiddle(Role role) {
        // 所有的菜单ID
        List<Integer> ids = role.getIds();
        if (!CollectionUtils.isEmpty(ids)) {
            // 要保存的菜单
            Set<Integer> parentIds = menuService.listByIds(ids)
                    .stream().map(Menu::getParentId)
                    .collect(Collectors.toSet());

            // 要保存的所有ID
            parentIds.addAll(ids);

            Integer rid = role.getId();
            List<RoleMenu> roleMenus = new ArrayList<>();
            parentIds.forEach(item -> {
                roleMenus.add(new RoleMenu(item, rid));

            });
            roleMenuService.saveBatch(roleMenus);
        }
    }
}
